package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.product.ex.ServiceCode;
import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.BrandMapper;
import cn.tedu.csmall.product.pojo.dto.BrandAddNewDTO;
import cn.tedu.csmall.product.pojo.dto.BrandUpdateDTO;
import cn.tedu.csmall.product.pojo.entity.Brand;
import cn.tedu.csmall.product.pojo.vo.BrandListItemVO;
import cn.tedu.csmall.product.pojo.vo.BrandStandardVO;
import cn.tedu.csmall.product.repository.IBrandCacheRepository;
import cn.tedu.csmall.product.service.IBrandService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;
import java.util.List;

import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class BrandServiceImpl implements IBrandService {

    @Autowired
    BrandMapper mapper;


    /**
     * 添加品牌
     * @param brandAddNewDTO  品牌数据
     */
    @Override
    public void addNew(BrandAddNewDTO brandAddNewDTO) {
        int num=mapper.countByName(brandAddNewDTO.getName());

        if(num>0){
            String message="添加品牌失败，品牌名称【"+brandAddNewDTO.getName()+"】已经被占用。";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
            //log.debug("该品牌已存在！");
            //return "品牌已存在！";
        }
        Brand brand=new Brand();
        BeanUtils.copyProperties(brandAddNewDTO,brand);
        brand.setSales(0);
        brand.setProductCount(0);
        brand.setCommentCount(0);
        brand.setPositiveCommentCount(0);
        log.info("准备添加品牌{}！",brand);
        int row=mapper.insert(brand);
        if(row!=1){
            String message="添加品牌失败，服务器忙，请稍后尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
    }

    @Override
    public void deleteById(Long id) {

        BrandStandardVO brandStandardVO=mapper.getStandardById(id);
        if(brandStandardVO==null){
            String message="删除失败,id为"+id+"的数据不存在";
            log.debug("删除失败，id为{}的数据不存在！",id);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        int row=mapper.deleteById(id);
        if(row!=1){
            String message="删除失败,系统繁忙，请稍后重试！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_DELETE,message);
        }
        log.debug("删除品牌成功！");
    }

    @Override
    public void setEnable(Long id) {
        //根据id获取品牌表对象
        BrandStandardVO queryResult=mapper.getStandardById(id);
        //获取获取的对象为null，则表示数据不存在，抛出异常，错误代码：ERR_NOT_FOUND，错误信息：启用失败，该数据不存在！
        if(queryResult==null){
            String message="启用失败，该数据不存在！";
            log.debug("启用失败，id为{}的数据不存在！",id);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        //如果数据存在但是当前enable状态为1，抛出异常，错误代码：ERR_CONFLICT，错误信息：启用失败，该品牌已经是启动状态!
        if(queryResult.getEnable()==1){
            String message="启用失败，该品牌已经是启动状态!";
            log.debug("启用失败，id为{}的数据已经是启用状态！",id);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //如果数据存在且enable状态不为1，创建品牌对象，调用mapper接口的updateId()方法
        Brand brand=new Brand();
        brand.setEnable(1);
        brand.setId(id);
        int row=mapper.updateById(brand);
        //update方法返回的受影响行数不唯一，则表示修改失败，抛出异常，异常代码：ERR_UPDATE，错误信息：启用失败，系统繁忙，请稍后重试！
        if(row!=1){
            String message="启用失败，系统繁忙，请稍后重试！";
            log.debug("启用失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为{}的品牌启用成功！",id);
    }

    @Override
    public void setUnEnable(Long id) {
        //根据id查询品牌表是否存在该数据
        BrandStandardVO queryResult=mapper.getStandardById(id);
        //如果不存在，抛出异常，错误代码：ERR_NOT_FOUNT,错误信息：禁用失败，该数据不存在！
        if(queryResult==null){
            String message="禁用失败，该数据不存在！";
            log.debug("禁用失败，id为{}的数据不存在！",id);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }

        //如果数据存在但当前状态已经是被禁用，则抛出异常，错误代码：ERR_CONFLICT，错误信息：禁用失败，该品牌已经是禁用状态!
        if(queryResult.getEnable()==0){
            String message="禁用失败，该品牌已经是禁用状态!";
            log.debug("禁用失败，id为{}的数据已经是禁用状态！",id);
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        //数据存在且状态代码不为0，创建品牌对象，设置品牌id和enable属性，执行mapper接口的updateById()方法
        Brand brand=new Brand();
        brand.setEnable(0);
        brand.setId(id);
        int row=mapper.updateById(brand);
        //row为修改数据是品牌表受影响的行数，若不为1，抛出异常，错误代码：ERR_UPDATE，错误信息：禁用失败，系统繁忙，请稍后重试！
        if(row!=1){
            String message="禁用失败，系统繁忙，请稍后重试！";
            log.debug("禁用失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("id为{}的品牌禁用成功！",id);
    }

    @Override
    public void updateById(Long id,BrandUpdateDTO brandUpdateDTO) {
        log.debug("更新品牌【{}】信息！",brandUpdateDTO.getName());
        String brandName=brandUpdateDTO.getName();
        //查询被修改的品牌数据是否存在
        BrandStandardVO queryResult = mapper.getStandardById(id);
        //如果不能存在
        if(queryResult==null){
            //抛出not_found异常
            String message="修改失败，品牌"+brandName+"不存在！";
            log.debug("修改失败，品牌【{}】不存在！",brandName);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        log.debug("品牌【{}】存在！准备修改品牌信息！",brandName);

        //创建brand对象
        Brand brand=new Brand();
        //把DTO对象复制到brand对象中
        BeanUtils.copyProperties(brandUpdateDTO,brand);
        //调用mapper接口的update方法
        brand.setId(id);
        int rows=mapper.updateById(brand);
        //获取被修改的数据行数是否等于1
        //如果不等于1，抛出异常
        if(rows!=1){
            //抛出异常
            String message="修改失败，系统繁忙，请稍后重试！";
            log.debug("修改失败，系统繁忙，请稍后重试！");
            throw new ServiceException(ServiceCode.ERR_UPDATE,message);
        }
        log.debug("品牌【{}】信息修改成功！",brandName);
        //修改成功，输出日志
    }

    /**
     * 根据id获取品牌详情
     * @param id 根据id获取品牌详情
     * @return
     */
    @Override
    public BrandStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据id获取品牌详情】请求");
        /*BrandStandardVO brand = mapper.getStandardById(id);*/
        BrandStandardVO brand = brandCacheRepository.get(id);
        if(brand==null){
            String message="获取品牌详情失败，尝试访问的数据不存在！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND,message);
        }
        return brand;
    }

    /**
     * 获取品牌列表
     * @return
     */
    @Override
    public List<BrandListItemVO> list() {
        log.debug("开始获取【品牌列表】");

        /*return mapper.list();*/
        return brandCacheRepository.getList();
    }

    @Autowired
    IBrandCacheRepository brandCacheRepository;

    @Override
    public void loadBrandsToCache() {
        //获取所有品牌数据在缓存中key
        Set<String> allKeys = brandCacheRepository.getAllKeys();

        //删除原有的缓存数据
        brandCacheRepository.deleteAll(allKeys);

        //将品牌列表存入到缓存中
        List<BrandListItemVO> list = mapper.list();
        brandCacheRepository.saveList(list);

        //将各品牌数据存入到缓存中
        for (BrandListItemVO brandListItemVO : list) {
            BrandStandardVO brandStandardVO =
                    mapper.getStandardById(brandListItemVO.getId());
            brandCacheRepository.save(brandStandardVO);
        }
    }

}
